#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 6/22/2018 7:27 PM
# @Author  : Edwin
# @Version : Python 3.6
# @File    : data_processing.py

#保存数据
import pickle

import itertools

#处理事件字符串
import datetime

import numpy as np
import scipy.io as sio
import scipy.sparse as ss
import pandas as pd
import csv


from collections import defaultdict


# 统计训练集中有多少不同的用户的events
uniqueUsers = set()
uniqueEvents = set()


#倒排表
#统计每个用户参加的活动   / 每个活动参加的用户
eventsForUser = defaultdict(set)
usersForEvent = defaultdict(set)

for filename in ["train.csv","test.csv"]:
    f = open(filename)

    f.readline().strip().split(',')

    for line in f:
        cols = line.strip().split(',')
        uniqueUsers.add(cols[0])
        uniqueEvents.add(cols[1])
    f.close()
n_uniqueUsers = len(uniqueUsers)
n_uniqueEvents = len(uniqueEvents)

print("number of uniqueUsers :%d" % n_uniqueUsers)
print("number of uniqueEvents :%d" % n_uniqueEvents)

#用户关系矩阵表，可用于后续LFM/SVD++处理的输入
#这是一个稀疏矩阵，记录用户对活动感兴趣
userEventScores = ss.dok_matrix((n_uniqueUsers, n_uniqueEvents))
userIndex = dict()
eventIndex = dict()

#重新编码用户索引字典
for i ,u in enumerate(uniqueUsers):
    userIndex[u] = i

for i,e in enumerate(uniqueEvents):
    eventIndex[e] = i


n_record = 0
ftrain = open("train.csv")
ftrain.readline()
for line in ftrain:
    cols = line.strip().split(",")
    i = userIndex[cols[0]]
    j = eventIndex[cols[1]]

    eventsForUser[i].add(j)   #该用户参加了这个活动
    usersForEvent[j].add(i)   #该活动被用户参加

    score = int(cols[4])

    userEventScores[i,j] = score

ftrain.close()

# 为了防止不必要的计算，我们找出来所有关联的用户 或者 关联的event
# 所谓的关联用户，指的是至少在同一个event上有行为的用户pair
# 关联的event指的是至少同一个user有行为的event pair
uniqueUserPairs = set()
uniqueEventPairs = set()

for even in uniqueEvents:
    i = eventIndex[even]
    user = usersForEvent[i]

    if len(user) > 2:
        uniqueUserPairs.update(itertools.combinations(user,2))

for user in uniqueUsers:
    i = userIndex[user]
    events = eventsForUser[i]
    if len(events) > 2:
        uniqueEventPairs.update(itertools.combinations(events,2))

#统计每个用户参加的活动，后续用于将用户朋友参加的活动影响到用户
pickle.dump(eventsForUser, open("eventsForUser.pkl", 'wb'))
#统计活动参加的用户
pickle.dump(usersForEvent, open("usersForEvent.pkl", 'wb'))
#保存用户-活动关系矩阵R，以备后用
usereventscore_array = userEventScores.toarray()
sio.mmwrite("userEventScores", userEventScores)
pickle.dump(usereventscore_array, open("usereventscore_array.pkl", 'wb'))
#保存用户索引表
pickle.dump(userIndex, open("userIndex.pkl", 'wb'))
#保存活动索引表
pickle.dump(eventIndex, open("eventIndex.pkl", 'wb'))
# 保存用户-事件关系对索引表
pickle.dump(uniqueUserPairs, open("FE_uniqueUserPairs.pkl", 'wb'))
pickle.dump(uniqueEventPairs, open("PE_uniqueEventPairs.pkl", 'wb'))

